using System.Collections.Generic;

namespace DownloadBook {
    /// <summary>
    /// 动态广告服务层
    /// </summary>
    public class DynamicAdServer{
        
        /// <summary>
        /// 移除动态广告
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string doRemoveDynamicAd(List<DynamicAd> dynamicAdList, string str) {
            if(dynamicAdList.Count > 0){
                int startIndex, endIndex;
                for (int i = 0; i < dynamicAdList.Count; i++) {
                    //获取动态广告示例
                    DynamicAd dynamicAdvertising = dynamicAdList[i];

                    //查找广告内容
                    while (doFindDynamicAd(dynamicAdvertising, str, out startIndex, out endIndex)) {
                        string left = str.Substring(0, startIndex);
                        string right = str.Substring(endIndex);
                        str = left + right;

                        //重置变量，下次重新使用
                        startIndex = endIndex = -1;
                    }
                }
            }
            return str;
        }

        /// <summary>
        /// 查找动态广告
        /// </summary>
        /// <param name="dynamicAd"></param>
        /// <param name="str"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <returns></returns>
        private bool doFindDynamicAd(DynamicAd dynamicAd, string str, out int startIndex, out int endIndex) {
            bool result = false;
            startIndex = endIndex = -1;
            int minContentCount = dynamicAd.minContentCount;
            int contentCount = 0;
            if (dynamicAd != null) {
                int index = dynamicAd.header;

                //开始遍历关键字
                for (int i = 0; i < dynamicAd.contentList.Length; i++) {
                    string content = dynamicAd.contentList[i];
                    int startIndexLocal = -1, endIndexLocal = -1;
                    if (content != null && content.Length > 0) {//如果条件有效
                        //处理动态广告项
                        int contentCountOrigin = contentCount;
                        int indexOrigin = index;
                        if (this.doHandleDynamicAdItem(dynamicAd, content, str, ref index, ref contentCount, ref startIndexLocal, ref endIndexLocal)) {
                            if (endIndexLocal > startIndexLocal) {
                                //如果能找到
                                if (startIndex == -1) {
                                    startIndex = startIndexLocal;
                                } else {//如果原先不是-1了
                                    int step = startIndexLocal - endIndex;
                                    if (step > dynamicAd.maxStep) {//如果超过最大跨度了

                                        //恢复记录
                                        contentCount = contentCountOrigin;
                                        index = indexOrigin;

                                        //说明不符合条件，开始下一个
                                        continue;
                                    }
                                }


                                //计算出动态广告在这个时候的结束点
                                endIndex = endIndexLocal;

                                //重新定位下次开始搜索的位置
                                index = endIndex + 1;

                                //计算是成功了
                                result = contentCount >= minContentCount;
                            }

                            //重置，让下次循环从 0 开始
                            i = -1;
                        }
                    }
                }
            }

            if(result){
                startIndex -= dynamicAd.header;
                endIndex += dynamicAd.tail;
            }
            return result;
        }

        /// <summary>
        /// 处理动态广告项目
        /// </summary>
        /// <param name="dynamicAd"></param>
        /// <param name="content"></param>
        /// <param name="str"></param>
        /// <param name="index"></param>
        /// <param name="contentCount"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <returns></returns>
        protected bool doHandleDynamicAdItem(DynamicAd dynamicAd, string content, string str, ref int index, ref int contentCount, ref int startIndex, ref int endIndex){
            //环境
            int adMinLength = dynamicAd.header + dynamicAd.tail + content.Length;
            int maxStep = dynamicAd.maxStep;
            bool hasFound = false;
            
            int startIndexLocal, endIndexLocal;
            while (str.Length - index > adMinLength) {
                if(!this.doFindDynamicAdItem(str, dynamicAd, content, index, out startIndexLocal, out endIndexLocal)){//如果找不到了
                    break;
                }

                //如果能找到
                if (startIndex == -1) {
                    startIndex = startIndexLocal;
                } else {//如果原先不是-1了
                    int step = startIndexLocal - endIndex;
                    if (step > maxStep) {//如果超过最大跨度了
                        hasFound = endIndex > startIndex;
                        break;
                    }
                }
                endIndex = endIndexLocal;
                index = endIndex;
                contentCount++;
                hasFound = true;
            }

            return hasFound;
        }

        /// <summary>
        /// 查找动态广告项
        /// </summary>
        /// <param name="str"></param>
        /// <param name="dynamicAd"></param>
        /// <param name="content"></param>
        /// <param name="index"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <returns></returns>
        protected bool doFindDynamicAdItem(string str, DynamicAd dynamicAd, string content, int index, out int startIndex, out int endIndex){
            startIndex = endIndex = -1;
            bool result = false;
            
            int maxStep = dynamicAd.maxStep;
            while (index < str.Length) {
                int startIndexLocal = str.IndexOf(content[0], index);
                if (startIndexLocal == -1) {
                    break;
                }

                //如果第一个字符找到了
                int nextStartIndex = startIndexLocal + 1;

                //先临时标记为成功
                result = true;
                for (int i = 1; i < content.Length; i++) {
                    char c = content[i];
                    int indexLocal = str.IndexOf(c, nextStartIndex);
                    if (indexLocal == -1) {//如果没找到下一个字符串
                        result = false;
                        break;//不符合需求
                    }

                    //计算出步进个数
                    int step = indexLocal - nextStartIndex;
                    if (step > maxStep) {//如果超过了限额
                        result = false;
                        break;//不符合需求
                    }

                    //更新下次查找的索引
                    nextStartIndex = indexLocal + 1;
                }

                //以防万一二次验证
                result &= nextStartIndex > startIndexLocal;

                if (result) {
                    startIndex = startIndexLocal;
                    endIndex = nextStartIndex;
                    break;
                }

                index = startIndexLocal + 1;
            }
            return result;
        }
    }
}